/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#ifndef __43F82E27_9099_4ff3_B1F5_9A81A2C05110__
#define __43F82E27_9099_4ff3_B1F5_9A81A2C05110__

#include "../tools/head.h"

//////////////////////////////////////////////////////////////////////////////////////////
// 

namespace xos_box
{
    class serial_impl : public xos_stl::mem_item< xos::release_impl< serial_impl >, thread_lock >,
		public i_serial
    {
    public:
        typedef xos::release_impl< serial_impl > T;

    public:
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //

        static int get_xos_item_data( ITEM_DATA*& item_ptr );

    public:
        serial_impl();
        ~serial_impl();

    public:
        int init();
        int term();

    public:
        // 
        // char *
        // 
        int un_pack_str_array( const char * lpszData, int * lpnPos, int * lpnLen, int nBufSize, char * lppszStr, int nStrNum, int * lpnStrNum, int * lpnStrNumNeeded );
        int un_pack_str( const char * lpszData, int * lpnPos, int * lpnLen, char * lpszStr, int nBufSize, int * lpnStrLen, int * lpnStrLenNeeded );
        int pack_str_array( char * lpszData, int nPos, int * lpnLen, int * lpnLenLeft, int nBufSize, const char * lppszStr, int nStrNum );
        int pack_str( char * lpszData, int nPos, int * lpnLen, int * lpnLenLeft, const char * lpszStr );

        int un_pack_mem_array( const char * lpszData, int * lpnPos, int * lpnLen, int nBufSize, char * lppszMem, int * lpnMemLen, int nMemNum, int * lpnMemNum, int * lpnMemNumNeeded );
        int un_pack_mem( const char * lpszData, int * lpnPos, int * lpnLen, char * lpszMem, int nBufSize, int * lpnMemLen, int * lpnMemLenNeeded );
        int pack_mem_array( char * lpszData, int nPos, int * lpnLen, int * lpnLenLeft, int nBufSize, const char * lppszMem, int * lpnMemLen, int nMemNum );
        int pack_mem( char * lpszData, int nPos, int * lpnLen, int * lpnLenLeft, const char * lpszMem, int nMemLen );

        int un_pack_int8_array( const char * lpszData, int * lpnPos, int * lpnLen, uint8_t * lpuData, int nNum, int * lpnNum, int * lpNumNeeded );
        int un_pack_int8( const char * lpszData, int * lpnPos, int * lpnLen, uint8_t * lpuData );
        int pack_int8_array( char * lpszData, int nPos, int * lpnLen, int * lpnLenLeft, uint8_t * lpuData, int nNum );
        int pack_int8( char * lpszData, int nPos, int * lpnLen, int * lpnLenLeft, uint8_t uData );

        int un_pack_int16_array( const char * lpszData, int * lpnPos, int * lpnLen, uint16_t * lpuData, int nNum, int * lpnNum, int * lpNumNeeded );
        int un_pack_int16( const char * lpszData, int * lpnPos, int * lpnLen, uint16_t * lpuData );
        int pack_int16_array( char * lpszData, int nPos, int * lpnLen, int * lpnLenLeft, uint16_t * lpuData, int nNum );
        int pack_int16( char * lpszData, int nPos, int * lpnLen, int * lpnLenLeft, uint16_t uData );

        int un_pack_int32_array( const char * lpszData, int * lpnPos, int * lpnLen, uint32_t * lpuData, int nNum, int * lpnNum, int * lpNumNeeded );
        int un_pack_int32( const char * lpszData, int * lpnPos, int * lpnLen, uint32_t * lpuData );
        int pack_int32_array( char * lpszData, int nPos, int * lpnLen, int * lpnLenLeft, uint32_t * lpuData, int nNum );
        int pack_int32( char * lpszData, int nPos, int * lpnLen, int * lpnLenLeft, uint32_t uData );

        int un_pack_int64_array( const char * lpszData, int * lpnPos, int * lpnLen, uint64_t * lpuData, int nNum, int * lpnNum, int * lpNumNeeded );
        int un_pack_int64( const char * lpszData, int * lpnPos, int * lpnLen, uint64_t * lpuData );
        int pack_int64_array( char * lpszData, int nPos, int * lpnLen, int * lpnLenLeft, uint64_t * lpuData, int nNum );
        int pack_int64( char * lpszData, int nPos, int * lpnLen, int * lpnLenLeft, uint64_t uData );

        int un_pack_float_array( const char * lpszData, int * lpnPos, int * lpnLen, float * lpfData, int nNum, int * lpnNum, int * lpNumNeeded );
        int un_pack_float( const char * lpszData, int * lpnPos, int * lpnLen, float * lpfData );
        int pack_float_array( char * lpszData, int nPos, int * lpnLen, int * lpnLenLeft, float * lpfData, int nNum );
        int pack_float( char * lpszData, int nPos, int * lpnLen, int * lpnLenLeft, float fData );

        int un_pack_double_array( const char * lpszData, int * lpnPos, int * lpnLen, double * lpdData, int nNum, int * lpnNum, int * lpNumNeeded );
        int un_pack_double( const char * lpszData, int * lpnPos, int * lpnLen, double * lpdData );
        int pack_double_array( char * lpszData, int nPos, int * lpnLen, int * lpnLenLeft, double * lpdData, int nNum );
        int pack_double( char * lpszData, int nPos, int * lpnLen, int * lpnLenLeft, double dData );

        //
        // // 带有int * lpnAbsolutePos版本不影响xos_box::i_buf状态，只是在绝对位置开始pack数据。
        // xos_box::i_buf *
        // 
        int un_pack_str_array( xos_box::i_buf * pBuf, int nBufSize, char * lppszStr, int nStrNum, int * lpnStrNum, int * lpnStrNumNeeded );
        int un_pack_str( xos_box::i_buf * pBuf, char * lpszStr, int nBufSize, int * lpnStrLen, int * lpnStrLenNeeded );
        int pack_str_array( xos_box::i_buf * pBuf, int * lpnAbsolutePos, int nBufSize, const char * lppszStr, int nStrNum );
        int pack_str( xos_box::i_buf * pBuf, int * lpnAbsolutePos, const char * lpszStr );
        int pack_str_array( xos_box::i_buf * pBuf, int nBufSize, const char * lppszStr, int nStrNum );
        int pack_str( xos_box::i_buf * pBuf, const char * lpszStr );

        int un_pack_mem_array( xos_box::i_buf * pBuf, int nBufSize, char * lppszMem, int * lpnMemLen, int nMemNum, int * lpnMemNum, int * lpnMemNumNeeded );
        int un_pack_mem( xos_box::i_buf * pBuf, char * lpszMem, int nBufSize, int * lpnMemLen, int * lpnMemLenNeeded );
        int pack_mem_array( xos_box::i_buf * pBuf, int * lpnAbsolutePos, int nBufSize, const char * lppszMem, int * lpnMemLen, int nMemNum );
        int pack_mem( xos_box::i_buf * pBuf, int * lpnAbsolutePos, const char * lpszMem, int nMemLen );
        int pack_mem_array( xos_box::i_buf * pBuf, int nBufSize, const char * lppszMem, int * lpnMemLen, int nMemNum );
        int pack_mem( xos_box::i_buf * pBuf, const char * lpszMem, int nMemLen );

        int un_pack_int8_array( xos_box::i_buf * pBuf, uint8_t * lpuData, int nNum, int * lpnNum, int * lpNumNeeded );
        int un_pack_int8( xos_box::i_buf * pBuf, uint8_t * lpuData );
        int pack_int8_array( xos_box::i_buf * pBuf, int * lpnAbsolutePos, uint8_t * lpuData, int nNum );
        int pack_int8( xos_box::i_buf * pBuf, int * lpnAbsolutePos, uint8_t uData );
        int pack_int8_array( xos_box::i_buf * pBuf, uint8_t * lpuData, int nNum );
        int pack_int8( xos_box::i_buf * pBuf, uint8_t uData );

        int un_pack_int16_array( xos_box::i_buf * pBuf, uint16_t * lpuData, int nNum, int * lpnNum, int * lpNumNeeded );
        int un_pack_int16( xos_box::i_buf * pBuf, uint16_t * lpuData );
        int pack_int16_array( xos_box::i_buf * pBuf, int * lpnAbsolutePos, uint16_t * lpuData, int nNum );
        int pack_int16( xos_box::i_buf * pBuf, int * lpnAbsolutePos, uint16_t uData );
        int pack_int16_array( xos_box::i_buf * pBuf, uint16_t * lpuData, int nNum );
        int pack_int16( xos_box::i_buf * pBuf, uint16_t uData );

        int un_pack_int32_array( xos_box::i_buf * pBuf, uint32_t * lpuData, int nNum, int * lpnNum, int * lpNumNeeded );
        int un_pack_int32( xos_box::i_buf * pBuf, uint32_t * lpuData );
        int pack_int32_array( xos_box::i_buf * pBuf, int * lpnAbsolutePos, uint32_t * lpuData, int nNum );
        int pack_int32( xos_box::i_buf * pBuf, int * lpnAbsolutePos, uint32_t uData );
        int pack_int32_array( xos_box::i_buf * pBuf, uint32_t * lpuData, int nNum );
        int pack_int32( xos_box::i_buf * pBuf, uint32_t uData );

        int un_pack_int64_array( xos_box::i_buf * pBuf, uint64_t * lpuData, int nNum, int * lpnNum, int * lpNumNeeded );
        int un_pack_int64( xos_box::i_buf * pBuf, uint64_t * lpuData );
        int pack_int64_array( xos_box::i_buf * pBuf, int * lpnAbsolutePos, uint64_t * lpuData, int nNum );
        int pack_int64( xos_box::i_buf * pBuf, int * lpnAbsolutePos, uint64_t uData );
        int pack_int64_array( xos_box::i_buf * pBuf, uint64_t * lpuData, int nNum );
        int pack_int64( xos_box::i_buf * pBuf, uint64_t uData );

        int un_pack_float_array( xos_box::i_buf * pBuf, float * lpfData, int nNum, int * lpnNum, int * lpNumNeeded );
        int un_pack_float( xos_box::i_buf * pBuf, float * lpfData );
        int pack_float_array( xos_box::i_buf * pBuf, int * lpnAbsolutePos, float * lpfData, int nNum );
        int pack_float( xos_box::i_buf * pBuf, int * lpnAbsolutePos, float fData );
        int pack_float_array( xos_box::i_buf * pBuf, float * lpfData, int nNum );
        int pack_float( xos_box::i_buf * pBuf, float fData );

        int un_pack_double_array( xos_box::i_buf * pBuf, double * lpdData, int nNum, int * lpnNum, int * lpNumNeeded );
        int un_pack_double( xos_box::i_buf * pBuf, double * lpdData );
        int pack_double_array( xos_box::i_buf * pBuf, int * lpnAbsolutePos, double * lpdData, int nNum );
        int pack_double( xos_box::i_buf * pBuf, int * lpnAbsolutePos, double dData );
        int pack_double_array( xos_box::i_buf * pBuf, double * lpdData, int nNum );
        int pack_double( xos_box::i_buf * pBuf, double dData );

		// 
		// 根据xos_box::i_buf中的当前进度和上次的pos, len进度，检查是否可以合下一包数据。考虑需要预留包头的字节数
		//		nRet是pack执行结果，0 : 成功，非0，失败。pack_end用它判断如果处理xos_box::i_buf中的pos和len
		// 返回值定义：
		//		0 : 成功，可以继续，已经读取xos_box::i_buf中的pos和len
		//      1 : 成功，不能继续，已经读取xos_box::i_buf中的pos和len
		//     -1 : 失败，没有操作
		// 
		int pack_end( xos_box::i_buf * pBuf, int & nBufPos, int & nBufLen, int nRet, int nPackageHeadLen );

		// 
		// 只是简单的把xos_box::i_buf中的pos和len保存到nBufPos和nBufLen中
		// 
		int pack_begin( xos_box::i_buf * pBuf, int & nBufPos, int & nBufLen );

    };
} // xos_common

#endif // __43F82E27_9099_4ff3_B1F5_9A81A2C05110__
